#ifndef _H_C_TCP_ACCEPTOR_IMPL_H_
#define _H_C_TCP_ACCEPTOR_IMPL_H_

#include "../typedefine.h"
#include "ENetErrorCode.h"
#include "../coroutine.h"
#include <deque>
#include <memory>
#if _WIN32
#include <winsock2.h>
#else
#include <sys/socket.h>
#endif

namespace TB
{
	class CNetService;
	class CTcpSocket;

	class CTcpAcceptorImpl
	{
		NON_COPYABLE(CTcpAcceptorImpl)
		NON_MOVEABLE(CTcpAcceptorImpl)

	public:
		CTcpAcceptorImpl();
		~CTcpAcceptorImpl();
		inline std::weak_ptr<CNetService>& GetNetService() { return m_poNetService; }
		inline const std::weak_ptr<CNetService>& GetNetService() const { return m_poNetService; }
		bool Init(const std::weak_ptr<CNetService>& poNetService, const std::weak_ptr<CTcpAcceptorImpl>& poSelf);
		ENetErrorCode Listen(UINT32 dwIP, UINT16 wPort, UINT32 dwBacklog); //主机字节序
		void Accept(STaskProcessor<std::pair<ENetErrorCode, std::shared_ptr<CTcpSocket>>>& rsTaskProcessor);
		bool GetLocalIpPort(std::pair<UINT32, UINT16>& roIpPort) const; //主机字节序
		bool IsClosed() const;
		void Close();
		bool SetReuseAddr(bool bReuse = true);

	private:
		void _Accept();
		bool _AddPoll();
		bool _RemovePoll();

	private:
		std::weak_ptr<CNetService> m_poNetService;
		std::weak_ptr<CTcpAcceptorImpl> m_poSelf;
		std::deque<STaskProcessor<std::pair<ENetErrorCode, std::shared_ptr<CTcpSocket>>>> m_oAcceptTaskQueue;
		bool m_bAddedToPoll = false;
#if _WIN32
		SOCKET m_nAcceptorFD = INVALID_SOCKET;
#else
		int m_nAcceptorFD = -1;
#endif
	};
}

#endif